package q1.project.modules.system.role.service;

import java.util.List;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import q1.project.common.context.TenantContext;
import q1.project.common.enums.EnableStatusEnum;
import q1.project.core.exception.BusinessException;
import q1.project.core.jpa.WhereBuilderNow;
import q1.project.modules.system.role.dao.PermissionDao;
import q1.project.modules.system.role.entity.PermissionEntity;
import q1.project.modules.system.role.model.PermissionVm;

/**
 * 权限服务实现
 *
 * @author Q1 Team
 * @version 1.0
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class PermissionService {

  private final PermissionDao permissionDao;

  @Transactional(rollbackFor = Exception.class)
  public PermissionVm.PermissionResponse createPermission(PermissionEntity permission) {
    log.info("创建权限: permissionCode={}", permission.getPermissionCode());

    // 校验权限编码是否已存在
    if (permissionDao.findByPermissionCode(permission.getPermissionCode()).isPresent()) {
      log.warn("权限编码已存在: {}", permission.getPermissionCode());
      throw new BusinessException("权限编码已存在");
    }

    permission = permissionDao.save(permission);
    log.info(
        "权限创建成功: id={}, permissionCode={}", permission.getId(), permission.getPermissionCode());

    return convertToResponse(permission);
  }

  @Transactional(rollbackFor = Exception.class)
  public PermissionVm.PermissionResponse updatePermission(PermissionEntity permission) {
    log.info("更新权限: id={}", permission.getId());

    PermissionEntity existingPermission =
        permissionDao
            .findById(permission.getId())
            .orElseThrow(() -> new BusinessException("权限不存在"));

    // 更新基本信息
    existingPermission.setPermissionName(permission.getPermissionName());
    existingPermission.setModule(permission.getModule());
    existingPermission.setAction(permission.getAction());
    existingPermission.setDescription(permission.getDescription());
    existingPermission.setStatus(permission.getStatus());

    existingPermission = permissionDao.save(existingPermission);
    log.info(
        "权限更新成功: id={}, permissionCode={}",
        existingPermission.getId(),
        existingPermission.getPermissionCode());

    return convertToResponse(existingPermission);
  }

  @Transactional(rollbackFor = Exception.class)
  public void deletePermission(String id) {
    log.info("删除权限: id={}", id);

    PermissionEntity permission =
        permissionDao.findById(id).orElseThrow(() -> new BusinessException("权限不存在"));

    permissionDao.delete(permission);

    log.info("权限删除成功: id={}, permissionCode={}", id, permission.getPermissionCode());
  }

  public PermissionVm.PermissionResponse getPermissionById(String id) {
    log.debug("查询权限: id={}", id);

    PermissionEntity permission =
        permissionDao.findById(id).orElseThrow(() -> new BusinessException("权限不存在"));

    return convertToResponse(permission);
  }

  public PermissionVm.PermissionResponse getPermissionByCode(String permissionCode) {
    log.debug("根据权限编码查询权限: permissionCode={}", permissionCode);

    PermissionEntity permission =
        permissionDao
            .findByPermissionCode(permissionCode)
            .orElseThrow(() -> new BusinessException("权限不存在"));

    return convertToResponse(permission);
  }

  public Page<PermissionVm.PermissionResponse> listPermissions(PermissionVm.PermissionQuery query) {
    log.debug(
        "分页查询权限: page={}, size={}, keyword={}, permissionCode={}, permissionName={}, status={}, type={}",
        query.getPage(),
        query.getSize(),
        query.getKeyword(),
        query.getPermissionCode(),
        query.getPermissionName(),
        query.getStatus(),
        query.getType());

    query.validate();
    String tenantId = TenantContext.getTenantId();

    // 使用WhereBuilderNow构建动态查询条件
    WhereBuilderNow<PermissionEntity> builder = new WhereBuilderNow<>();
    builder.init(query);

    Specification<PermissionEntity> spec =
        builder.build(
            w -> {
              // 租户ID条件（必须）
              w.stringEqual("tenantId", tenantId);

              // 权限编码模糊查询
              if (StringUtils.hasText(query.getPermissionCode())) {
                w.stringContain("permissionCode", query.getPermissionCode());
              }

              // 权限名称模糊查询
              if (StringUtils.hasText(query.getPermissionName())) {
                w.stringContain("permissionName", query.getPermissionName());
              }

              // 状态精确查询
              if (StringUtils.hasText(query.getStatus())) {
                try {
                  EnableStatusEnum status = EnableStatusEnum.valueOf(query.getStatus());
                  w.enumEqual("status", status);
                } catch (IllegalArgumentException e) {
                  log.warn("无效的权限状态: {}", query.getStatus());
                }
              }

              // 模块查询（根据PermissionEntity的实际字段）
              if (StringUtils.hasText(query.getType())) {
                // type参数可能对应module字段，需要根据实际业务调整
                w.stringEqual("module", query.getType());
              }

              // 关键词搜索（如果有关键词，在多个字段中搜索）
              if (StringUtils.hasText(query.getKeyword())) {
                w.keywordSearch(
                    query.getKeyword(),
                    "permissionCode",
                    "permissionName",
                    "module",
                    "action",
                    "description");
              }

              // 排序：按创建时间降序
              w.descOrder("createTime");
            });

    // 执行查询
    Page<PermissionEntity> page = permissionDao.findAll(spec, builder.getPageable());

    return page.map(this::convertToResponse);
  }

  public List<PermissionVm.PermissionResponse> listPermissionsByModule(String module) {
    log.debug("根据模块查询权限: module={}", module);

    List<PermissionEntity> permissions = permissionDao.findByModule(module);

    return permissions.stream().map(this::convertToResponse).collect(Collectors.toList());
  }

  public List<PermissionVm.PermissionResponse> listEnabledPermissions() {
    log.debug("查询所有启用的权限");

    List<PermissionEntity> permissions = permissionDao.findByStatus(EnableStatusEnum.ACTIVE);

    return permissions.stream().map(this::convertToResponse).collect(Collectors.toList());
  }

  /** 转换为VO对象 */
  private PermissionVm.PermissionResponse convertToResponse(PermissionEntity entity) {
    return new PermissionVm.PermissionResponse(
        entity.getId(),
        entity.getPermissionCode(),
        entity.getPermissionName(),
        entity.getDescription(),
        entity.getModule(),
        entity.getResource(),
        entity.getAction(),
        entity.getStatus());
  }
}
